package com.zkzl.cdz.handler;

import com.zkzl.cdz.dao.ChargeStation;
import com.zkzl.cdz.dao.CmdStructure;
import com.zkzl.cdz.dao.SysDao;
import com.zkzl.cdz.netty.MangerChannel;
import com.zkzl.cdz.netty.MethodInvokeMeta;
import com.zkzl.cdz.netty.RequestDispatcher;
import com.zkzl.cdz.util.Tools;
import io.netty.channel.Channel;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

/**
 * @Description: 多线程共享(线程池)
 * @Author: jww
 * @CreateDate: 2019/8/7 14:07
 * @Version: 1.0.0
 */
@Component
@ChannelHandler.Sharable
@Slf4j
public class ChargeHandler extends ChannelInboundHandlerAdapter {

    /**
     * 注入请求分排器
     */
    @Autowired
    private RequestDispatcher dispatcher;

    @Autowired
    SysDao sysDao;

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) {
        ctx.fireExceptionCaught(cause);
        Channel channel = ctx.channel();
        if (!channel.isActive()) {
            ctx.close();
        }
        String code = MangerChannel.getCode(channel);
        if (code != null) {
            ChargeStation stationMsg = sysDao.findStationMsg(code);
            if (stationMsg != null) {
                String address = stationMsg.getAddress();
                String name = stationMsg.getName();
                log.error(address + "的" + name + ",失败原因 : ", cause.getMessage());
            }
        }
        log.error("失败原因 : ", cause.getMessage());
    }

    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) {
        MethodInvokeMeta invokeMeta = new MethodInvokeMeta();
        /*if (msg instanceof ByteBuf) {
            byte[] bytes = new byte[((ByteBuf) msg).readableBytes()];
            ((ByteBuf) msg).readBytes(bytes);
            log.info("第二次收到的数据" + new String(bytes));
        } else */
        if (((byte[]) msg).length < 12) {

        } else {
            byte[] message = (byte[]) msg;
            CmdStructure cs = new CmdStructure();
            cs.serial = message[6];
            cs.gun = message[7];
            cs.type = message[8];
            cs.body = new byte[message.length - 12];//此处嗯呵呵
            System.arraycopy(message, 9, cs.body, 0, message.length - 12);
            log.info("收到的指令内容--->" + cs.toString());
            String className = "com.zkzl.cdz.command.Cmd_0x" + Tools.byteToHex(cs.type);
            Class<?> interfaceClass = null;
            try {
                interfaceClass = Class.forName(className);
            } catch (ClassNotFoundException e) {
                log.error("系统内无相应命令", e);
            }
            invokeMeta.setInterfaceClass(interfaceClass);
            invokeMeta.setParameterTypes(new Class[]{ChannelHandlerContext.class, CmdStructure.class});
            invokeMeta.setMethodName("Execute");
            invokeMeta.setArgs(new Object[]{ctx, cs});
            dispatcher.dispatcher(ctx, invokeMeta);
            //ctx.flush();
        }
    }

    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        log.info("---" + ctx.channel().remoteAddress() + " is active---");
    }

    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        log.info("---" + ctx.channel().remoteAddress() + " is inactive---");
    }
}
